#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
//using namespace std;



//This function threshold the HSV image and create a binary image
IplImage* GetThresholdedImage(IplImage* imgHSV){
       IplImage* imgThresh=cvCreateImage(cvGetSize(imgHSV),IPL_DEPTH_8U, 1);
       cvInRangeS(imgHSV, cvScalar(170,160,60,0), cvScalar(180,256,255,0), imgThresh);
       return imgThresh;
}


int main()
{

//IplImage* imgThresh =  cvLoadImage(frame,CV_LOAD_IMAGE_COLOR);
 CvCapture* capture =0;
 int i;

      capture = cvCaptureFromCAM(1);
      if(!capture){
            printf("Capture failure\n");
            return -1;
      }

      IplImage* frame=0;

//show the original image
cvNamedWindow("Original",0);
cvShowImage("Original",frame);
while(1)
{



frame = cvQueryFrame(capture);
            if(!frame) break;

            frame=cvCloneImage(frame);
            cvSmooth(frame, frame, CV_GAUSSIAN,3,3,0,0); //smooth the original image using Gaussian kernel

            IplImage* imgHSV = cvCreateImage(cvGetSize(frame), IPL_DEPTH_8U, 3);
            cvCvtColor(frame, imgHSV, CV_BGR2HSV); //Change the color format from BGR to HSV
            IplImage* imgThresh = GetThresholdedImage(imgHSV);

            cvSmooth(imgThresh, imgThresh, CV_GAUSSIAN,3,3,0,0); //smooth the binary image using Gaussian kernel

            //track the possition of the ball

 //smooth the original image using Gaussian kernel to remove noise
//cvSmooth(img, img, CV_GAUSSIAN,3,3);

//converting the original image into grayscale
IplImage* imgGrayScale = cvCreateImage(cvGetSize(imgHSV), 8, 1);
cvCvtColor(imgHSV,imgGrayScale,CV_BGR2GRAY);

cvNamedWindow("GrayScale Image",CV_WINDOW_AUTOSIZE);
cvShowImage("GrayScale Image",imgGrayScale);

//thresholding the grayscale image to get better results
cvThreshold(imgGrayScale,imgGrayScale,100,255,CV_THRESH_BINARY_INV);

cvNamedWindow("Thresholded Image",CV_WINDOW_AUTOSIZE);
cvShowImage("Thresholded Image",imgGrayScale);

CvSeq* contour;  //hold the pointer to a contour
CvSeq* result;   //hold sequence of points of a contour
CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours

//finding all contours in the image
cvFindContours(imgGrayScale, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));

//iterating through each contour
while(contour)
{
//obtain a sequence of points of the countour, pointed by the variable 'countour'
result = cvApproxPoly(contour, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contour)*0.02, 0);

//if there are 3 vertices  in the contour and the area of the triangle is more than 100 pixels
if(result->total==3 && fabs(cvContourArea(result, CV_WHOLE_SEQ,0))>100 )
{
//iterating through each point
CvPoint *pt[3];
for( i=0;i<3;i++){
pt[i] = (CvPoint*)cvGetSeqElem(result, i);
}

//drawing lines around the triangle
cvLine(frame, *pt[0], *pt[1], cvScalar(255,0,0,0),4,8,0);
cvLine(frame, *pt[1], *pt[2], cvScalar(255,0,0,0),4,8,0);
cvLine(frame, *pt[2], *pt[0], cvScalar(255,0,0,0),4,8,0);

}

//obtain the next contour
contour = contour->h_next;
}

//show the image in which identified shapes are marked
cvNamedWindow("Tracked",CV_WINDOW_AUTOSIZE);
cvShowImage("Tracked",frame);



cvWaitKey(0); //wait for a key press
cvReleaseCapture(&capture);
cvReleaseMemStorage(&storage);
cvReleaseImage(&imgHSV);
cvReleaseImage(&imgGrayScale);
}

//cleaning up
cvDestroyAllWindows();
cvReleaseCapture(&capture);
//cvReleaseMemStorage(&storage);
//cvReleaseImage(&img);
//cvReleaseImage(&imgGrayScale);

return 0;
}

